package chaincode

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

const (
	TR_RecordID_UNIKEY = "TR-RecordID"
)

/**
 * @Description:代煎数据批量上链
 * @receiver d
 * @param APIstub
 * @param args
 * @return pb.Response
 */
type IngredientsExchangeCC struct{}

func (c *IngredientsExchangeCC) uploadRecipes(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//验证参数
	if len(args) != 2 {
		return shim.Error(NewErrInfo(ERR_NUM_PARAME, nil).Error())
	}
	//获取机构MSPID
	orgMspID, err := getTraderMspID(stub)
	if err != nil {
		return shim.Error(err.Error())
	}
	//解析参数
	var (
		TisaneRecords []*TisaneRecord
		EventType     = args[1]
	)
	err = json.Unmarshal([]byte(args[0]), &TisaneRecords)
	if err != nil {
		return shim.Error(NewErrInfo(ERR_UNMARSHAL, err).Error())
	}
	//循环遍历参数
	for _, TisaneRecord := range TisaneRecords {
		RecipeCodeName := TisaneRecord.RecipeCode + base64.StdEncoding.EncodeToString([]byte(TisaneRecord.Name))
		//解析提交参数
		recipeKey, err := stub.CreateCompositeKey(TR_RecordID_UNIKEY, []string{"H", GenerateRecordKey(TisaneRecord.HospitalCode, RecipeCodeName)})
		if err != nil {
			return shim.Error(NewErrInfo(ERR_CREATE_COMPKEY, err).Error())
		}
		tisaneRecord, err := stub.GetState(recipeKey)
		if err != nil {
			return shim.Error(NewErrInfo(ERR_GET_STATE, err).Error())
		}
		if tisaneRecord != nil {
			return shim.Error(NewErrInfo(ERR_KV_EXIST, fmt.Errorf("%d:%v:%v", TisaneRecord.HospitalCode, TisaneRecord.RecipeCode, TisaneRecord.Name)).Error())
		}

		err = stub.PutState(recipeKey, tisaneRecord)
		if err != nil {
			return shim.Error(NewErrInfo(ERR_PUT_STATE, err).Error())
		}
	}
	//通知事件
	evBytes, err := NewEventMessage(orgMspID, EventType, []byte(args[0])).Marshal()
	if err != nil {
		return shim.Error(err.Error())
	}

	err = stub.SetEvent(EventType, evBytes)
	if err != nil {
		return shim.Error(NewErrInfo(ERR_SET_EVENT, err).Error())
	}
	return shim.Success(nil)

}
func (c *IngredientsExchangeCC) QueryRecipes(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//检查参数的个数
	if len(args) != 1 {
		return shim.Error(NewErrInfo(ERR_NUM_PARAME, nil).Error())
	}
	var (
		vaildQueryParam *VaildQueryParam
	)
	err := json.Unmarshal([]byte(args[0]), &vaildQueryParam)
	if err != nil {
		return shim.Error(NewErrInfo(ERR_UNMARSHAL, err).Error())
	}
	recipeCode := vaildQueryParam.RecipeCode
	hospitalCode := vaildQueryParam.HospitalCode
	name := vaildQueryParam.Name
	if recipeCode == "" || hospitalCode == "" || name == "" {
		return shim.Error(NewErrInfo(ERR_EMPTY_PARAME, err).Error())
	}
	RecipeCodeName := vaildQueryParam.RecipeCode + base64.StdEncoding.EncodeToString([]byte(vaildQueryParam.Name))
	//解析提交参数
	recipeKey, err := stub.CreateCompositeKey(TR_RecordID_UNIKEY, []string{"H", GenerateRecordKey(vaildQueryParam.HospitalCode, RecipeCodeName)})
	//验证数据是否存在
	userBytes, err := stub.GetState(recipeKey)
	if err != nil || len(userBytes) == 0 {
		return shim.Error(NewErrInfo(ERR_NOT_EXIST, err).Error())
	}
	return shim.Success(userBytes)
}
func (c *IngredientsExchangeCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
	return shim.Success(nil)
}

func (c *IngredientsExchangeCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	funcName, args := stub.GetFunctionAndParameters()

	switch funcName {
	case "uploadRecipes":
		return c.uploadRecipes(stub, args)
	case "QueryRecipes":
		return c.QueryRecipes(stub, args)

	default:
		return shim.Error(fmt.Sprintf("unsupported function: %s", funcName))
	}

}
func main() {
	err := shim.Start(new(IngredientsExchangeCC))
	if err != nil {
		fmt.Printf("Error starting AssertsExchange chaincode: %s", err)
	}
}
